<?

class Event {

	protected  $stopped;
	protected static $handlers;
	protected $target;
	protected $from;
	protected $cancelled;
	protected static $init;
	protected $type;
	protected $handler;

	protected $nl = array();

	function __construct ($target, $evt_type,  $params = array()) {
		if (!self::$init)  return;
		$this->type = $evt_type;
		$this->target = $target;
		$target = $this->from;
			
		//$query = "SELECT * FROM `trigger` WHERE `rt` = '$this->target' AND `rid` = '$rid' AND `action` = '$evt_type'";
		//TODO: record defined handlers
			
		$this->fireEvent();

		if(key_exists('%', self::$handlers)) {
			$this->handler[0] = '%';
			if (key_exists($this->type, self::$handlers)) {
				$this->handler[1] = $this->type;
				$this->target = $this->target;
				$handlers = self::$handlers['%'][$this->type];
				for ($x=0;$x<count($handlers);$x++) {
					call_user_func($handlers[$x], $this);
					if ($this->stopped) return;
				}
			}

			if (key_exists('%', self::$handlers['%'])) {
				$this->handler[1] = '%';
				$this->target = array($this->target, $rid);
				$handlers = self::$handlers['%']['%'];
				for ($x=0;$x<count($handlers);$x++) {
					call_user_func($handlers[$x], $this);
					if ($this->stopped) return;
				}

			}
		}
			
	}

	protected function fireEvent() {

		if(key_exists($this->target, self::$handlers)) {
			$this->handler[0] = $this->target;
			if (key_exists($this->type, self::$handlers)) {
				$this->handler[1] = $this->type;
				$handlers = self::$handlers[$this->target][$this->type];
				for ($x=0;$x<count($handlers);$x++) {
					call_user_func($handlers[$x], $this);
					if ($this->stopped) return;
				}
			}
			if (key_exists('%', self::$handlers[$this->target])) {
				$this->handler[1] = '%';
				$handlers = self::$handlers[$this->target]['%'];
				for ($x=0;$x<count($handlers);$x++) {
					call_user_func($handlers[$x], $this);
					if ($this->stopped) return;
				}
			}
		}

		$this->nl[$rt.'['.$rid.']'] = true;
			

	}

	function stop() {
		$this->stopped = true;
	}

	static function setHandler($target, $type, $handler) {
		self::$handlers[$target][$type][] = $handler;
		self::$init = true;
		return true;
	}

	function __get($n) {
		if ($n == 'cancelled') return $this->cancelled;
		elseif ($n == 'type') return $this->type;
		elseif ($n == 'nl') return $this->nl;
		elseif ($n == 'target') return $this->target;
		elseif ($n == 'from') return $this->from;
		elseif ($n == 'handler') return $this->handler;
	}

	function cancel() {
		$this->cancelled = true;
		$this->stopped = true;
	}
}



class DBEVENT {
	const BEFORE_INSERT = 101;
	const AFTER_INSERT = 151;
	const BEFORE_UPDATE = 102;
	const AFTER_UPDATE = 152;
	const BEFORE_DELETE = 103;
	const AFTER_DELETE = 153;
	const BEFORE_SELECT = 104;
	const AFTER_SELECT = 154;

	static function name($code) {
		switch ($code) {
			case 101:
				return 'DBEVENT::BEFORE_INSERT';
				break;
			case 151:
				return 'DBEVENT::AFTER_INSERT';
				break;
			case 102:
				return 'DBEVENT::BEFORE_UPDATE';
				break;
			case 152:
				return 'DBEVENT::AFTER_UPDATE';
				break;
			case 103:
				return 'DBEVENT::BEFORE_DELETE';
				break;
			case 153:
				return 'DBEVENT::AFTER_DELETE';
				break;
			case 104:
				return 'DBEVENT::BEFORE_SELECT';
				break;
			case 154:
				return 'DBEVENT::AFTER_SELECT';
				break;
					
			default:
				return 'DBEVENT::UNKNOWN';
				break;
		}
	}
}